home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d16 / wsmooth.arc / WSMSRC.ARC / WSMOOTH.C < prev    next >
C/C++ Source or Header  |  1990-10-09  |  18KB  |  577 lines

  1. // wsmooth.c RHS 9/1/90
  2.  
  3. #include"windows.h"
  4. #include"wsmooth.h"
  5. #include"wsmooth2.h"
  6. #include<stdio.h>
  7. #include<string.h>
  8. #include<malloc.h>
  9. #include<stdarg.h>
  10. #include<process.h>
  11. #include<math.h>
  12. #include"filebuf.h"
  13.  
  14. #define textrowsperpage()   ((PixRowsPerPage/CharLineHeight)+3)
  15.  
  16. #define SB_PIXLINEUP    (SB_LINEUP+0x0100)
  17. #define SB_PIXLINEDOWN  (SB_LINEDOWN+0x0100)
  18.  
  19. long numlines;
  20. HWND WinSmooth = 0;
  21. char filename[128];
  22. char classname[11] = "WinSmooth";
  23. char windowname[128] = "WinSmooth";
  24. BOOL direction = DOWN;
  25.  
  26. HANDLE hOrgBrush;
  27. HCURSOR hNormalCursor, hHourGlassCursor;
  28. BOOL sb_init = FALSE;
  29.  
  30. SETTINGS settings =
  31.     {
  32.     DEFAULTMSECS,
  33.     DEFAULTPIXELROWS,
  34.     DEFAULTBACK,
  35.     DEFAULTFORE,
  36.     FALSE
  37.     };
  38.  
  39. HANDLE hinstance;
  40.  
  41. void ResetPixRows(void);
  42. void ResetBackGround(HDC hDC);
  43. void RetrieveSettings(void);
  44. void PaintMainWindow(HWND hwnd);
  45.  
  46.    // beginning of WinSmooth
  47. int PASCAL WinMain(HANDLE hInstance,HANDLE hPrevInstance,
  48.     LPSTR lpszCmdLine, int cmdShow)
  49.     {
  50.     MSG msg;
  51.  
  52.     RetrieveSettings();                 // retrieve settings from WIN.INI
  53.     lstrcpy((LPSTR)filename,lpszCmdLine);
  54.     process_cmdline(filename);          // get (and override with) command-line settings
  55.  
  56.     hOrgBrush = CreateSolidBrush(settings.back);
  57.  
  58.     if(!hPrevInstance)
  59.         {
  60.         WNDCLASS cl;
  61.  
  62.         cl.lpszClassName = (LPSTR) classname;
  63.         cl.hInstance = hInstance;
  64.         cl.lpfnWndProc = MainWindowProc;
  65.         cl.hCursor = LoadCursor(NULL, IDC_ARROW);
  66.         cl.hIcon = LoadIcon(hInstance,(LPSTR)"WSMOOTH");
  67.         cl.lpszMenuName = (LPSTR)"FILEMENU";
  68.         cl.hbrBackground = hOrgBrush;
  69.         cl.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
  70.         cl.cbClsExtra = 0;
  71.         cl.cbWndExtra = 0;
  72.  
  73.         if(!RegisterClass(&cl))
  74.             return FALSE;
  75.         hNormalCursor = cl.hCursor;
  76.         }
  77.  
  78.     hHourGlassCursor = LoadCursor(NULL, IDC_WAIT);
  79.     WinSmooth = CreateWindow((LPSTR)classname,
  80.         (LPSTR)windowname,
  81.         WS_OVERLAPPEDWINDOW | WS_VSCROLL,
  82.         CW_USEDEFAULT,
  83.         CW_USEDEFAULT,
  84.         CW_USEDEFAULT,
  85.         CW_USEDEFAULT,
  86.         NULL,
  87.         NULL,
  88.         hInstance,
  89.         (LPSTR)NULL);
  90.  
  91.     if(!WinSmooth)
  92.         return FALSE;
  93.  
  94.     ShowWindow(WinSmooth, cmdShow);
  95.     UpdateWindow(WinSmooth);
  96.     hinstance = hInstance;
  97.     ChangeTitleBar(filename);           // in case it wasn't done when file was opened
  98.  
  99.     while(GetMessage(&msg, NULL, 0, 0))
  100.         {
  101.         TranslateMessage(&msg);
  102.         DispatchMessage(&msg);
  103.         }
  104.     exit(msg.wParam);
  105.     }
  106.  
  107.    // WinSmooth termination and cleanup
  108. BOOL FAR PASCAL CloseApplication(void)
  109.     {
  110.     filebuf_destruct();
  111.     return TRUE;
  112.     }
  113.  
  114. struct _keytable
  115.     {
  116.     WORD    virkey;
  117.     int     msg;
  118.     WORD    sbcode;
  119.     } keyscroll[] =
  120.     {
  121.     VK_PRIOR,   WM_VSCROLL,     SB_PAGEUP,
  122.     VK_NEXT,    WM_VSCROLL,     SB_PAGEDOWN,
  123.     VK_HOME,    WM_VSCROLL,     SB_TOP,
  124.     VK_END,     WM_VSCROLL,     SB_BOTTOM,
  125.     VK_UP,      WM_VSCROLL,     SB_LINEUP,
  126.     VK_DOWN,    WM_VSCROLL,     SB_LINEDOWN
  127.     };
  128. #define MAXKEYS (sizeof(keyscroll) / sizeof(keyscroll[0]))
  129.  
  130. #define MYTIMER         1
  131. #define RBUTTONDCLICK   2
  132.  
  133.    // main window procedure for WinSmooth
  134. long FAR PASCAL MainWindowProc(HWND hwnd, unsigned message, WORD wParam, LONG lParam)
  135.     {
  136.     static BOOL paused = TRUE, rbdclk = FALSE, app_activated = TRUE;
  137.     static BOOL restart = TRUE;
  138.     FARPROC lpProcAbout, lpOpenDialog, lpSettingsDialog;
  139.  
  140.     switch(message)
  141.         {
  142.                     //////////// Windows Messages
  143.         case WM_CREATE:
  144.             {
  145.             if(!WSopenfile(filename))
  146.                 PostMessage(hwnd,WM_COMMAND,IDM_OPEN,0L);
  147.             else
  148.                 PostMessage(hwnd,WM_WSM_STARTTIMER,0,0L);
  149.             }
  150.             break;
  151.  
  152.         case WM_PAINT:
  153.             PaintMainWindow(hwnd);
  154.             break;
  155.  
  156.         case WM_TIMER:                  // timer message
  157.             switch(wParam)
  158.                 {
  159.                 case MYTIMER:
  160.                     if(settings.PixelRows > 0)
  161.                         PostMessage(hwnd,WM_VSCROLL,
  162.                             (direction == DOWN) ? SB_PIXLINEDOWN : SB_PIXLINEUP,0L);
  163.                     break;
  164.                 case RBUTTONDCLICK:
  165.                     KillTimer(hwnd,RBUTTONDCLICK);
  166.                     if(!rbdclk)
  167.                         PostMessage(hwnd,WM_RBUTTONDOWN,MY_RBUTTON,0L);
  168.                     else
  169.                         rbdclk = FALSE;
  170.                     break;
  171.                 }
  172.             break;
  173.  
  174.         case WM_VSCROLL:                // vertical scrollbar message
  175.             ProcessVscroll(hwnd, wParam, lParam);
  176.             break;
  177.  
  178.         case WM_CLOSE:                  // close application
  179.             DestroyWindow(hwnd);
  180.             break;
  181.  
  182.         case WM_DESTROY:                // destroy application
  183.             CloseApplication();
  184.             KillTimer(hwnd,MYTIMER);
  185.             DeleteObject(hOrgBrush);
  186.             PostQuitMessage(0);
  187.             break;
  188.  
  189.         case WM_INITMENU:               // stop timer when User uses menu
  190.             restart = (paused ? FALSE : TRUE);
  191.             SendMessage(hwnd,WM_WSM_STOPTIMER,0,0L);
  192.             break;
  193.  
  194.         case WM_ACTIVATE:               // if activation message sent
  195.             if(wParam == 0)
  196.                 app_activated = FALSE;
  197.             break;
  198.  
  199.         case WM_COMMAND:                // menu messages
  200.             {
  201.             switch(wParam)
  202.                 {
  203.                 case IDM_OPEN:          // open a new file
  204.                     {
  205.                     int newfile,fileisopen = filebuf_fileisopen();
  206.  
  207.                     lpOpenDialog = MakeProcInstance(OpenDlg, hinstance);
  208.                     // Open the file and get its handle
  209.                     newfile = DialogBox(hinstance, "OPEN", hwnd, lpOpenDialog);
  210.                     FreeProcInstance(lpOpenDialog);
  211.                     if(newfile)
  212.                         {
  213.                         sb_init = FALSE;
  214.                         SendMessage(hwnd,WM_VSCROLL,SB_TOP,0L);
  215.                         InvalidateRect(hwnd, NULL, TRUE);
  216.                         SendMessage(hwnd,WM_PAINT,0,0L);
  217.                         }
  218.                     else if(!fileisopen)
  219.                         {
  220.                         int i;
  221.  
  222.                         if((i = MessageBox(hwnd,"Terminate WinSmooth?","WinSmooth",
  223.                                 MB_OKCANCEL | MB_ICONQUESTION)) == IDOK)
  224.                             PostMessage(hwnd,WM_CLOSE,0,0L);
  225.                         else
  226.                             PostMessage(hwnd,WM_COMMAND,IDM_OPEN,0L);
  227.                         }
  228.                     }
  229.                     break;
  230.  
  231.                 case IDM_ABOUT:         // display About box
  232.                     lpProcAbout = MakeProcInstance(About, hinstance);
  233.                     DialogBox(hinstance, "ABOUTBOX", hwnd, lpProcAbout);
  234.                     FreeProcInstance(lpProcAbout);
  235.                     break;
  236.  
  237.                 case IDM_SETTINGS:
  238.                     lpSettingsDialog = MakeProcInstance(Settings, hinstance);
  239.                     DialogBox(hinstance, "SETTINGS", hwnd, lpSettingsDialog);
  240.                     FreeProcInstance(lpSettingsDialog);
  241.                     break;
  242.  
  243.                 case IDM_EXIT:          // terminate program
  244.                     PostMessage(hwnd,WM_CLOSE,0,0L);
  245.                     break;
  246.  
  247.                 default:
  248.                     break;
  249.                 }
  250.             if(restart)
  251.                 SendMessage(hwnd,WM_WSM_STARTTIMER,0,0L);
  252.             }
  253.             break;
  254.  
  255.             //////////////////// Mouse Message Handling
  256.         case WM_LBUTTONDOWN:            // left mouse button == SPACE
  257.             if(app_activated)
  258.                 PostMessage(hwnd,WM_CHAR,SPACE,0L);
  259.             app_activated = TRUE;
  260.             break;
  261.  
  262.         case WM_RBUTTONDOWN:            // right mouse button == '-'
  263.             if(wParam == MY_RBUTTON)
  264.                 PostMessage(hwnd,WM_CHAR,'-',0L);
  265.             else
  266.                 {
  267.                 rbdclk = FALSE;
  268.                 SetTimer(hwnd,RBUTTONDCLICK,GetDoubleClickTime(),NULL);
  269.                 }
  270.             break;
  271.  
  272.         case WM_RBUTTONDBLCLK:          // right button Double click == '+'
  273.             rbdclk = TRUE;
  274.             PostMessage(hwnd,WM_WSM_INCPIXROWS,0,0L);
  275.             break;
  276.  
  277.             //////////////////// Keyboard Message handling
  278.         case WM_KEYDOWN:
  279.             {
  280.             int i;
  281.  
  282.             PostMessage(hwnd,WM_WSM_STARTTIMER,0,0L);
  283.             for(i = 0; i < MAXKEYS; i++)
  284.                 if(wParam == keyscroll[i].virkey)
  285.                     {
  286.                     SendMessage(hwnd,keyscroll[i].msg,keyscroll[i].sbcode,0L);
  287.                     break;
  288.                     }
  289.             }
  290.             break;
  291.  
  292.         case WM_CHAR:
  293.             PostMessage(hwnd,WM_WSM_STARTTIMER,0,0L);
  294.  
  295.             switch(wParam)
  296.                 {
  297.                 case ESC:               // quit the application
  298.                     PostMessage(hwnd,WM_CLOSE,0,0L);
  299.                     break;
  300.  
  301.                 case SPACE:             // stop the timer
  302.                     if(!paused)
  303.                         PostMessage(hwnd,WM_WSM_STOPTIMER,0,0L);
  304.                     break;
  305.  
  306.                 case '+':               // increase # of rows scrolled
  307.                     PostMessage(hwnd,WM_WSM_INCPIXROWS,0,0L);
  308.                     break;
  309.  
  310.                 case '-':               // decrease # of rows scrolled
  311.                     PostMessage(hwnd,WM_WSM_DECPIXROWS,0,0L);
  312.                     break;
  313.  
  314.                 default:                // if 0-9, set # of rows scrolled
  315.                     if(wParam >= '0' && wParam <= '9')
  316.                         settings.PixelRows = (wParam-'0');
  317.                     break;
  318.                 }
  319.             break;
  320.  
  321.             //////////////////// Application Messages
  322.         case WM_WSM_STARTTIMER:
  323.             if(paused && settings.PixelRows > MINPIXELROWS)
  324.                 SetTimer(hwnd,MYTIMER,settings.Msecs,NULL);
  325.             paused = FALSE;
  326.             break;
  327.  
  328.         case WM_WSM_STOPTIMER:
  329.             if(!paused)
  330.                 KillTimer(hwnd,MYTIMER);
  331.             paused = TRUE;
  332.             break;
  333.  
  334.         case WM_WSM_DECPIXROWS:
  335.             if(settings.PixelRows > MINPIXELROWS)
  336.                 settings.PixelRows--;
  337.             break;
  338.  
  339.         case WM_WSM_INCPIXROWS:
  340.             if(settings.PixelRows < MAXPIXELROWS)
  341.                 settings.PixelRows++;
  342.             break;
  343.  
  344.         case WM_WSM_HOURGLASS_CURSOR:
  345.             SetCursor(hHourGlassCursor);
  346.             break;
  347.  
  348.         case WM_WSM_NORMAL_CURSOR:
  349.             SetCursor(hNormalCursor);
  350.             break;
  351.  
  352.         case WM_SIZE:
  353.             ResetPixRows();             // fall thru in case icon'd
  354.         default:
  355.             return (DefWindowProc(hwnd, message, wParam, lParam));
  356.             break;
  357.         }
  358.     return (0L);
  359.     }
  360.  
  361. long NewPixTopRow = 0L, CurPixTopRow = 0L, BottPixRow = 0L;
  362. unsigned PixRowsPerPage = 0, CharLineHeight = 0, TextRowsPerPage;
  363.  
  364.    // vertical scroll processing for WinSmooth
  365. void ProcessVscroll(HWND hwnd, WORD wParam, LONG lParam)
  366.     {
  367.     BOOL bscroll = FALSE;
  368.  
  369.     switch(wParam)
  370.         {
  371.         case SB_PIXLINEUP:      // move up a pixel row
  372.             NewPixTopRow = CurPixTopRow - settings.PixelRows;
  373.             direction = UP;
  374.             break;
  375.         case SB_PIXLINEDOWN:    // move down a pixel row
  376.             NewPixTopRow = CurPixTopRow + settings.PixelRows;
  377.             direction = DOWN;
  378.             break;
  379.  
  380.         case SB_LINEUP:      // move up a character row
  381.             NewPixTopRow = CurPixTopRow - CharLineHeight;
  382.             direction = UP;
  383.             break;
  384.         case SB_LINEDOWN:    // move down a character row
  385.             NewPixTopRow = CurPixTopRow + CharLineHeight;
  386.             direction = DOWN;
  387.             break;
  388.         case SB_PAGEUP:        // move up a 'page' of rows
  389.             NewPixTopRow = CurPixTopRow - (PixRowsPerPage - 1);
  390.             break;
  391.         case SB_PAGEDOWN:    // move down a 'page' of rows
  392.             NewPixTopRow = CurPixTopRow + PixRowsPerPage - 1;
  393.             break;
  394.         case SB_TOP:        // go to top row
  395.             NewPixTopRow = 0L;
  396.             break;
  397.         case SB_BOTTOM:       // go to bottom row
  398.             if((NewPixTopRow = (BottPixRow-textrowsperpage())) < 0L)
  399.                 NewPixTopRow = 0L;
  400.             break;
  401.         case SB_THUMBPOSITION:    // reset to new position
  402.         case SB_THUMBTRACK:    // reset to new position
  403.             NewPixTopRow = (long)LOWORD(lParam);
  404.             NewPixTopRow *= CharLineHeight;
  405.             break;
  406.         }
  407.  
  408.     switch(wParam)
  409.         {
  410.         case SB_PIXLINEUP:
  411.         case SB_LINEUP:
  412.         case SB_PIXLINEDOWN:
  413.         case SB_LINEDOWN:
  414.         case SB_PAGEUP:
  415.         case SB_PAGEDOWN:
  416.         case SB_TOP:
  417.         case SB_BOTTOM:
  418.         case SB_THUMBPOSITION:
  419.             bscroll = TRUE;
  420.             break;
  421.         }
  422.     NewPixTopRow = max(NewPixTopRow, 0L);
  423.     NewPixTopRow = min(NewPixTopRow,BottPixRow);
  424.  
  425.     if(bscroll)
  426.         {
  427.         if((labs(NewPixTopRow - CurPixTopRow) < (long)PixRowsPerPage))
  428.             {
  429.             int temp1;
  430.             long temp2;
  431.  
  432.             temp2 = CurPixTopRow - NewPixTopRow;
  433.             temp1 = (int)temp2;
  434.             ScrollWindow(hwnd, 0,temp1,NULL,NULL);
  435.             }
  436.         else
  437.             InvalidateRect(hwnd, NULL, TRUE);
  438.         UpdateWindow(hwnd);
  439.         }
  440.     }
  441.  
  442. int Y, lineno;
  443.  
  444.    // WinSmooth paint procedure
  445. void PaintMainWindow(HWND hwnd)
  446.     {
  447.     PAINTSTRUCT ps;
  448.     HDC hdc;
  449.  
  450.     int TextTopRow, recttop, rectbott;
  451.     static int X, CharHeight;
  452.     int bottchar;
  453.  
  454.     BeginPaint(hwnd, &ps);
  455.     recttop = ps.rcPaint.top;
  456.     rectbott = ps.rcPaint.bottom;
  457.     hdc = ps.hdc;
  458.  
  459.     if(!sb_init)
  460.         {
  461.         TEXTMETRIC tmFontInfo;
  462.  
  463.         numlines = (long)filebuf_numlines();
  464.         GetTextMetrics(hdc, (LPTEXTMETRIC) &tmFontInfo);
  465.         CharLineHeight = tmFontInfo.tmExternalLeading + tmFontInfo.tmHeight;
  466.         CharHeight = tmFontInfo.tmHeight;
  467.         X = tmFontInfo.tmAveCharWidth;
  468.  
  469.         BottPixRow = (numlines*CharLineHeight);
  470.         SetScrollRange(hwnd,SB_VERT,0,(unsigned)numlines,TRUE);
  471.  
  472.         ResetBackGround(hdc);
  473.         ResetPixRows();
  474.         }
  475.  
  476.         // for writing the text...
  477.     SetBkMode(hdc,TRANSPARENT);         // has to be for back ground dithering
  478.     SetTextColor(hdc,settings.fore);
  479.     SetBkColor(hdc,settings.back);
  480.  
  481.     Y = (int)(NewPixTopRow%CharLineHeight)*-1;
  482.     if(sb_init)
  483.         Y--;
  484.     else
  485.         sb_init = TRUE;
  486.  
  487.     UnrealizeObject(hOrgBrush);
  488.     SetBrushOrg(hdc,0, (Y%8) ? (Y%8)+8 : 0);
  489.     SelectObject(hdc,hOrgBrush);
  490.  
  491.     if(Rectangle(hdc,ps.rcPaint.left,recttop,ps.rcPaint.right,ps.rcPaint.bottom))
  492.         FillRect(hdc,&ps.rcPaint,hOrgBrush);
  493.     SelectObject(hdc,hOrgBrush);
  494.  
  495.     TextTopRow = max(0u,(unsigned)(NewPixTopRow/CharLineHeight));
  496.  
  497.     for( lineno = TextTopRow; lineno < min((int)numlines, TextTopRow+TextRowsPerPage-1); lineno++)
  498.         {
  499.         bottchar = Y+CharHeight;
  500.  
  501.         if( ((rectbott-recttop+1 < (int)CharLineHeight) &&
  502.                 ((recttop >= Y && recttop <= bottchar) ||
  503.                  (rectbott >= Y && rectbott <= bottchar)))
  504.             ||
  505.  
  506.             (Y >= recttop && Y <= rectbott) ||
  507.             (bottchar >= recttop && bottchar <= rectbott))
  508.             {
  509.             LPSTR p;
  510.             unsigned len;
  511.  
  512.             filebuf_seekline(lineno);
  513.             p = filebuf_nextline(&len);
  514.             TextOut(hdc, X, Y, p, len);
  515.             }
  516.         Y += CharLineHeight;
  517.         }
  518.  
  519.     CurPixTopRow = NewPixTopRow;
  520.     SetScrollPos(hwnd,SB_VERT,(unsigned)(NewPixTopRow/CharLineHeight),TRUE);
  521.     ValidateRect(hwnd, (LPRECT)NULL);
  522.     EndPaint(hwnd, (LPPAINTSTRUCT) &ps);
  523.  
  524.     if((direction == DOWN) && (CurPixTopRow > (BottPixRow-textrowsperpage())))
  525.         direction = UP;
  526.     else if(CurPixTopRow == 0L && direction == UP)
  527.         direction = DOWN;
  528.     }
  529.  
  530.    // sets up background color for main window
  531. void ResetBackGround(HDC hDC)
  532.     {
  533.     HANDLE hOldBrush;
  534.  
  535.     hOrgBrush = CreateSolidBrush(settings.back);
  536.     hOldBrush = SelectObject(hDC,hOrgBrush);
  537.     DeleteObject(hOldBrush);
  538.     SetClassWord(WinSmooth,GCW_HBRBACKGROUND,hOrgBrush);
  539.     }
  540.  
  541.    // sets pixel row variable based on window size
  542. void ResetPixRows(void)
  543.     {
  544.     RECT    rect;
  545.  
  546.     if(WinSmooth)
  547.         {
  548.         GetClientRect(WinSmooth, &rect);
  549.         PixRowsPerPage = rect.bottom;
  550.         if(CharLineHeight)
  551.             TextRowsPerPage = textrowsperpage();
  552.         }
  553.     }
  554.  
  555. #define INIBUFSIZE 20
  556.    // retrieves WIN.INI settings for WinSmooth
  557. void RetrieveSettings(void)
  558.     {
  559.     char buf[INIBUFSIZE+1],defbuf[INIBUFSIZE+1];
  560.  
  561.     settings.Msecs = GetProfileInt((LPSTR)"WinSmooth",(LPSTR)"Msecs",settings.Msecs);
  562.     settings.PixelRows = GetProfileInt((LPSTR)"WinSmooth",(LPSTR)"PixelRows",settings.PixelRows);
  563.     
  564.     sprintf(defbuf,"%lu",settings.back);
  565.     GetProfileString((LPSTR)"WinSmooth",(LPSTR)"BackGround",(LPSTR)defbuf,(LPSTR)buf,INIBUFSIZE);
  566.     sscanf(buf,"%lu",&settings.back);
  567.  
  568.     sprintf(defbuf,"%lu",settings.fore);
  569.     GetProfileString((LPSTR)"WinSmooth",(LPSTR)"ForeGround",(LPSTR)defbuf,(LPSTR)buf,INIBUFSIZE);
  570.     sscanf(buf,"%lu",&settings.fore);
  571.  
  572.     settings.stripbits = GetProfileInt((LPSTR)"WinSmooth",(LPSTR)"StripBits",settings.stripbits);
  573.     }
  574.  
  575. // end of wsmooth.c
  576.  
  577.